package org.footito.android.connexion;

import java.io.BufferedInputStream;
import java.io.StringReader;
import java.net.URLEncoder;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.http.HttpResponse;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.ByteArrayBuffer;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import android.content.Context;
import android.os.AsyncTask;

public class FootitoConnexion {
	private static FootitoConnexion instance;

	private static final String LOGIN_URL_PASSWORD = "&password=";

	private static final String TAG = "Connexion";

	public static FootitoConnexion getInstance(Context context) {
		if (instance == null)
			instance = new FootitoConnexion(context);
		return instance;
	}
	private DefaultHttpClient client = NetworkTools.getNewHttpClient();
	private static final String LOGIN_URL_BASE = "http://api.footito.fr/api.php/user/login";
	private static final String LOGIN_URL_USERNAME = "?username=";
	private String login;

	private String password;
	private long userId = -1;
	private boolean isConnected = false;
	private Context context;

	private HttpResponse response;
	private CookieStore cookieStore;
	private FootitoConnexion(Context context) {
		this.context = context;
		login = "";
		password = "";
	}


	public boolean connect(ConnexionListener listener) {
		if (isConnected) {
			return true;
		} else {
			TaskConnect task = new TaskConnect(listener);
			task.execute((Void) null);
			return false;
		}
	}

	public final DefaultHttpClient getHttpClient() {
		if (client == null)
			client = NetworkTools.getNewHttpClient();
		return client;
	}

	private DefaultHttpClient getHttpNewClient() {
		client = null;
		return getHttpClient();
	}

	public String getLogin() {
		return login;
	}

	public String getPassword() {
		return password;
	}

	public long getUserId() {
		return userId;
	}

	public boolean isConnected() {
		return isConnected;
	}

	public void setLogin(String login) {
		unconnect();
		userId = -1;
		this.login = login;
	}

	public void setPassword(String password) {
		unconnect();
		userId = -1;
		this.password = password;
	}

	public boolean unconnect() { // TODO
		if (!isConnected) {
			return true;
		} else {
			client = null;
			isConnected = false;
			return false;
		}
	}

	private class TaskConnect extends AsyncTask<Void, Void, Void> {
		private Exception exception;
		private ConnexionApiHandler connexionApiHandler;
		private ConnexionListener listener;

		public TaskConnect(ConnexionListener listener) {
			this.listener = listener;
		}

		@Override
		protected Void doInBackground(Void... params) {
			DefaultHttpClient httpClient;

			httpClient = client;

			StringBuilder builder = new StringBuilder();
			builder.append(LOGIN_URL_BASE);
			builder.append(LOGIN_URL_USERNAME);
			builder.append(login);
			builder.append(LOGIN_URL_PASSWORD);
			builder.append(password);

			String uri = builder.toString();
			uri = URLEncoder.encode(uri);
			HttpGet request = new HttpGet(uri);

			try {
				response = httpClient.execute(request);

				// test

				System.out.println("Initial set of cookies:");
				List<Cookie> cookies = httpClient.getCookieStore().getCookies();
				if (cookies.isEmpty()) {
					System.out.println("None");
				} else {
					for (int i = 0; i < cookies.size(); i++) {
						System.out.println("- " + cookies.get(i).toString());
					}
				}
				// end test

				BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent());

				if (response.getStatusLine().getStatusCode() != 200) {
				}

				int cis = 0;
				ByteArrayBuffer baf = new ByteArrayBuffer(50);
				while ((cis = bis.read()) != -1) {
					baf.append((byte) cis);
				}

				bis.close();

				String res = new String(baf.toByteArray());

				SAXParserFactory spf = SAXParserFactory.newInstance();
				SAXParser sp = spf.newSAXParser();

				/* Get the XMLReader of the SAXParser we created. */
				XMLReader xr = sp.getXMLReader();

				/* Create a new ContentHandler and apply it to the XML-Reader */
				connexionApiHandler = new ConnexionApiHandler();
				xr.setContentHandler(connexionApiHandler);

				/* Parse the xml-data from our URL. */
				xr.parse(new InputSource(new StringReader(res)));

				userId = connexionApiHandler.getId();
			} catch (Exception e) {
				exception = e;
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			if (exception == null) {
				if (connexionApiHandler.getState() == 1 || connexionApiHandler.getState() == 2) {
					isConnected = true;
				}
				listener.onConnexionFinished(connexionApiHandler.getState());
			} else {
				listener.onConnexionFailed(exception);
			}
		}
	}

}
